#include "form_difficult.h"
#include "ui_form_difficult.h"

Form_difficult::Form_difficult(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::Form_difficult)
{
    ui->setupUi(this);
    istrue = false;
    score = 0;
    sec=0;
    fruit_index = -1;
    time_star = true;
    hurt_star = true;
    ui->label_6->setText(QString::number(sec));
    ui->label_2->setText(QString::number(score));
    ui->label_4->setText("50");
    gain("hp",3);
    gain("star",3);
    skin_name = "colorful_skin.jpg";
    barrier_skin = "apple.png";
    food_skin = "red_apple.png";
    foods_name.push_back("mushroom.png");
    foods_name.push_back("durian.png");
    foods_name.push_back("strawberry.png");
    foods_name.push_back("lemon.png");
    foods_name.push_back("banana.png");
    foods_name.push_back("juice.png");
    foods_name.push_back("mango.png");
    foods_name.push_back("ice_cream.png");
    foods_name.push_back("money.png");
    foods_name.push_back("orange.png");
    foods_name.push_back("pear.png");
    foods_name.push_back("salad.png");
    while(!random_set("player"));
    while(!random_set());
    while(!random_set("barrier"));
    while(!random_set("barrier"));
    timer = new QTimer;
    timer2 = new QTimer;
    speed = 400;
    timer->setInterval(speed);
    x = y = limit = limit2 = limit3 = 0;
    connect(timer,SIGNAL(timeout()),this,SLOT(move_slot()));
    connect(timer2,SIGNAL(timeout()),this,SLOT(time_slot()));
    connect(timer2,SIGNAL(timeout()),this,SLOT(speed_up()));
    connect(timer2,SIGNAL(timeout()),this,SLOT(slow_down()));
    connect(timer2,SIGNAL(timeout()),this,SLOT(change_color()));
    connect(timer,SIGNAL(timeout()),this,SLOT(shining()));
}

Form_difficult::~Form_difficult()
{
    delete ui;
}
void Form_difficult::time_slot()
{
    sec++;
    ui->label_6->setText(QString::number(sec));
    if(sec>200)
    {
        ui->label_6->setStyleSheet("color: rgb(255, 0, 0);");
        if(time_star)
        {
            time_star = false;
            lose("star");
        }
    }
    else
    {
        ui->label_6->setStyleSheet("");
        if(!time_star)
        {
            time_star = true;
            gain("star");
        }
    }
}
void Form_difficult::slow_down()
{
    if(limit3>0)
    {
        speed = 500;
        timer->setInterval(speed);
        limit3--;
    }
   else
    {
        speed=400;
        timer->setInterval(speed);
    }

}
void Form_difficult::speed_up()
{
    if(limit2>0)
    {
        speed = 300;
        timer->setInterval(speed);
        limit2--;
    }
   else
    {
        speed = 400;
        timer->setInterval(speed);
    }

}
void Form_difficult::change_color()
{
    if(limit>0)
    {
        for(int i=1;i<snake.size();i++)
        {
            snake[i]->setStyleSheet("border-image: url(:/image/3d_skin.jpg);");
        }
        limit--;
    }
   else if(limit==0)
    {
        for(int i=1;i<snake.size();i++)
        {
            snake[i]->setStyleSheet("border-image: url(:/image/"+skin_name+");");
        }
    }
}

void Form_difficult::lose(QString cmd,int num)
{
    if(cmd == "star")
    {
        for(int i=0;i<num;i++)
        {
            star = stars[stars.size()-1];
            stars.removeLast();
            delete star;
        }
    }
    else if(cmd == "hp")
    {
        if(x!=0) return;
        x=10;
        for(int i=0;i<num;i++)
        {
            hp = snakehp[snakehp.size()-1];
            snakehp.removeLast();
            delete hp;
        }
        if(hurt_star)
        {
            hurt_star = false;
            lose("star");
        }
        if(snakehp.size()==0)
        {
            qDebug("you lose!");
            initGame();
        }
    }
    else
    {
        qDebug("无效命令");
    }
}
void Form_difficult::gain(QString cmd,int num)
{
    if(cmd == "star")
    {
        if(stars.size()>=3) return;
        if(num+stars.size()>=3) num = 3-stars.size();
        for(int i=0;i<num;i++)
        {
            if(stars.size()==0)
            star = new Star(15,8,40,this);
            else
            star = new Star(stars[stars.size()-1]->x()/40+1,8,40,this);
            stars.push_back(star);
        }
    }
    else if(cmd == "hp")
    {
        if(snakehp.size()>=3) return;
        if(snakehp.size()+num>=3) num = 3-snakehp.size();
        for(int i=0;i<num;i++)
        {
            if(snakehp.size()>0)
            hp = new Food((snakehp[snakehp.size()-1]->x()/40)+1,0,40,this);
            else
            hp = new Food(15,0,40,this);
            hp->setStyleSheet("border-image: url(:/image/heart.png);");
            snakehp.push_back(hp);
        }
        if(snakehp.size()==3&&!hurt_star)
        {
            hurt_star = true;
            gain("star");
        }
    }
    else
    {
        qDebug("无效命令");
    }
}

void Form_difficult::shining()
{
    if(x>0)
    {
        for(int i=0;i<snake.size();i++)
        {
            if(!istrue)
            {
                snake[i]->close();
            }
            else
            {
                snake[i]->show();
            }
        }
        x--;
    }
    if(x==0)
    {
        for(int i=0;i<snake.size();i++)
        {
                snake[i]->show();
        }
    }
    istrue = !istrue;
}

void Form_difficult::initGame()
{
    score=sec=0;
    hurt_star = true;
    time_star = true;
    x = y = limit = limit2 = limit3 = 0;
    speed = 400;
    ui->label_2->setText(QString::number(score));
    ui->label_4->setText("50");
    ui->label_6->setStyleSheet("");
    ui->label_6->setText(QString::number(sec));
    clean_set();
    while(!random_set("player"));
    while(!random_set("barrier"));
    while(!random_set("barrier"));
    while(!random_set());
    gain("hp",3);
    gain("star",3);
    timer->stop();
    timer2->stop();
    ui->pushButton->show();
    ui->pushButton->setEnabled(true);
}

void Form_difficult::move_slot()
{
    for(int i=snake.size()-1; i>0; i--)
    {
        snake[i]->move(snake[i-1]->x(),snake[i-1]->y());
    }
    switch(dir)
    {
        case up:
            head->move(head->x(),head->y()-40);
            break;
        case down:
            head->move(head->x(),head->y()+40);
            break;
        case left:
            head->move(head->x()-40,head->y());
            break;
        case right:
            head->move(head->x()+40,head->y());
            break;
    }
    int qs = hit();
    switch(qs)
    {
        case 0: break;
        case 1: lose("hp"); break;
    case -1:score+=2;
        addEffect(fruit_index);
        clean_set("fruit");
        ui->label_2->setText(QString::number(score));
        if(score>=50)
        {
            qDebug("win!you get %d stars",stars.size());
            initGame();
        }
        break;
    default: getbody(qs-2); break;
    }

}
void Form_difficult::addEffect(int fruitindex)
{
    switch(fruitindex)
    {
        case 0:lose("hp");break;
        case 1:limit=10; break;
        case 2:gain("hp"); break;
        case 3:if(sec>10) sec-=10;else sec=0; break;
        case 4:limit2=10; break;
        case 5:while(!random_set("barrier")); break;
        case 6:clean_set("barrier"); break;
        case 7:x+=10; break;
        case 8:score+=5; break;
        case 9:limit3=10; break;
        case 10:sec+=10; break;
        case 11:if(sec>5) sec-=5;else sec=0; score+=3; gain("hp"); break;
        default:break;
    }
}
void Form_difficult::setDirection(int direction)
{
    QString headImage = "border-image: url(:/image/";
    switch(direction)
    {
        case up:
            headImage += "head_up.png);";
            break;
        case down:
            headImage += "head_down.png);";
            break;
        case left:
            headImage += "head_left.png);";
            break;
        case right:
            headImage += "head_right.png);";
            break;
    }
    head->setStyleSheet(headImage);
    this->dir = direction;
}

void Form_difficult::keyReleaseEvent(QKeyEvent *event)
{

    switch(event->key())
    {
        case Qt::Key_Up: setDirection(up);
            break;
        case Qt::Key_Down: setDirection(down);
            break;
        case Qt::Key_Left: setDirection(left);
            break;
        case Qt::Key_Right: setDirection(right);
            break;
        case Qt::Key_Space:
            timer->stop();
            timer2->stop();
            ui->pushButton->show();
            ui->pushButton->setEnabled(true);
            break;
    }

}
void Form_difficult::on_pushButton_clicked()
{
    timer->start(speed);
    timer2->start(1000);
    ui->pushButton->hide();
    ui->pushButton->setEnabled(false);
}
bool Form_difficult::random_set(QString cmd)
{
    if(cmd == "fruit")
    {
        clean_set("fruit");
        fruit = new Fruit(rand()%15,rand()%15,40,this);
        fruit_index = rand()%foods_name.size();
        fruit->setStyleSheet("border-image: url(:/image/"+foods_name[fruit_index]+");");
        int cnt=0;

        int size = foods.size();
        while(cnt<size)
        {
            if(fruit->x()==foods[cnt]->x()&&fruit->y()==foods[cnt]->y())
            {
                return false;
            }
            else
                cnt++;
        }
        cnt=0;

        size = wall.size();
        while(cnt<size)
        {
            if(fruit->x()==wall[cnt]->x()&&fruit->y()==wall[cnt]->y())
            {
                return false;
            }
            else
                cnt++;
        }
        cnt=0;

        size = snake.size();
        while(cnt<size)
        {
            if(fruit->x()==snake[cnt]->x()&&fruit->y()==snake[cnt]->y())
            {
                return false;
            }
            else
                cnt++;
        }
        return true;
    }
    else if(cmd == "food")
    {
        food = new Apple(rand()%15,rand()%15,40,this);
        food->setStyleSheet("border-image: url(:/image/"+food_skin+");");
        int cnt=0;
        int size = foods.size();
        while(cnt<size)
        {
            if(food->x()==foods[cnt]->x()&&food->y()==foods[cnt]->y())
            {
                delete food;
                return false;
            }
            else
                cnt++;
        }
        if(fruit_index>=0)
        {
            if(food->x()==fruit->x()&&food->y()==fruit->y())
            {
                delete food;
                return false;
            }
        }
        cnt=0;
        size = wall.size();
        while(cnt<size)
        {
            if(food->x()==wall[cnt]->x()&&food->y()==wall[cnt]->y())
            {
                delete food;
                return false;
            }
            else
                cnt++;
        }
        cnt=0;
        size = snake.size();
        while(cnt<size)
        {
            if(food->x()==snake[cnt]->x()&&food->y()==snake[cnt]->y())
            {
                delete food;
                return false;
            }
            else
                cnt++;
        }
        foods.push_back(food);
        return true;
    }
    else if(cmd == "barrier")
    {
        barrier = new Barrier(rand()%15,rand()%15,40,this);
        barrier->setStyleSheet("border-image: url(:/image/"+barrier_skin+");");
        int cnt=0;
        int size = foods.size();
        while(cnt<size)
        {
            if(barrier->x()==foods[cnt]->x()&&barrier->y()==foods[cnt]->y())
            {
                delete barrier;
                return false;
            }
            else
            cnt++;
        }
        if(fruit_index>=0)
        {
            if(fruit->x()==barrier->x()&&fruit->y()==barrier->y())
            {
                delete barrier;
                return false;
            }
        }
        cnt=0;

        size = wall.size();
        while(cnt<size)
        {
            if(barrier->x()==wall[cnt]->x()&&barrier->y()==wall[cnt]->y())
            {
                delete barrier;
                return false;
            }
            else
            cnt++;
        }
        cnt=0;

        size = snake.size();
        while(cnt<size)
        {
            if(barrier->x()==snake[cnt]->x()&&barrier->y()==snake[cnt]->y())
            {
                delete barrier;
                return false;
            }
            else
            cnt++;
        }
       wall.push_back(barrier);
       return true;
    }
    else if(cmd == "player")
    {
        head = new Food(rand()%15,rand()%15,40,this);
        head->setStyleSheet("border-image: url(:/image/"+skin_name+");");
        int cnt=0;
        int size = foods.size();
        while(cnt<size)
        {
            if(head->x()==foods[cnt]->x()&&head->y()==foods[cnt]->y())
            {
                delete head;
                return false;
            }
            else
            cnt++;
        }
        if(fruit_index>=0)
        {
            if(head->x()==barrier->x()&&head->y()==barrier->y())
            {
                delete head;
                return false;
            }
        }
        cnt=0;

        size = wall.size();
        while(cnt<size)
        {
            if(head->x()==wall[cnt]->x()&&head->y()==wall[cnt]->y())
            {
                delete head;
                return false;
            }
            else
            cnt++;
        }
        cnt=0;
        size = snake.size();
        while(cnt<size)
        {
            if(head->x()==snake[cnt]->x()&&head->y()==snake[cnt]->y())
            {
                delete head;
                return false;
            }
            else
            cnt++;
        }
       snake.push_back(head);
       setDirection(rand()%4);
       return true;
    }
    else
    {
        qDebug("无效命令");
        return false;
    }
}
void Form_difficult::clean_set(QString cmd)
{
    if(cmd=="food")
    {
        for(int it=0;it!=foods.size();it++)
        {
            delete foods[it];
        }
        foods.clear();
    }
    else if(cmd == "fruit")
    {
        if(fruit_index!=-1)
        {
            delete fruit;
            fruit_index=-1;
        }
    }
    else if(cmd == "player")
    {
        for(int it=0;it!=snake.size();it++)
        {
            delete snake[it];
        }
        snake.clear();
    }
    else if(cmd == "barrier")
    {
        for(int it=0;it!=wall.size();it++)
        {
            delete wall[it];
        }
        wall.clear();
    }
    else if(cmd == "all")
    {
        for(int it=0;it!=foods.size();it++)
        {
            delete foods[it];
        }
        foods.clear();
        if(fruit_index!=-1)
        {
            delete fruit;
            fruit_index=-1;
        }
        for(int it=0;it!=snake.size();it++)
        {
            delete snake[it];
        }
        snake.clear();
        for(int it=0;it!=wall.size();it++)
        {
            delete wall[it];
        }
        wall.clear();
    }
    else
    {
        qDebug("无效命令");
    }
}
int Form_difficult::hit()
{
    for(int i=1; i<snake.size(); i++)
    {
        if(snake[i]->x()==head->x()&&snake[i]->y()==head->y())
        {
            return 1;
        }
    }
    if(head->x()<0||head->y()<0||head->x()>=ui->widget->height()||head->y()>=ui->widget->width())
    {
        return 1;
    }
    if(fruit_index>=0)
    {
        if(fruit->x()==head->x()&&fruit->y()==head->y())
        {
            return -1;
        }
    }
    for(int cnt=0;cnt<foods.size();cnt++)
    {
        if(foods[cnt]->x() == head->x() && foods[cnt]->y() == head->y())
        {
            return 2+cnt;
        }
    }
    for(int i=0; i<wall.size(); i++)
    {
        if(wall[i]->x()==head->x()&&wall[i]->y()==head->y())
        {
            return 1;
        }
    }
    return 0;
}
void Form_difficult::getbody(int num)
{
    score++;
    if(rand()%10>0) while(!random_set("fruit"));
    ui->label_2->setText(QString::number(score));
    food = new Apple(snake[snake.size()-1]->x()/40,snake[snake.size()-1]->y()/40,40,this);
    snake.push_back(food);
    food->setStyleSheet("border-image: url(:/image/"+skin_name+");");
    delete foods[num];
    foods.erase(foods.begin()+num);
    while(!random_set());
    if(score>=50)
    {
        qDebug("win!you get %d stars",stars.size());
        initGame();
    }
}

